package com.kitty.game.rank.service.handler;

import com.kitty.game.role.model.Role;
import com.kitty.common.utils.SpringUtils;
import com.kitty.game.enter.FiedValue;
import com.kitty.game.rank.model.PersonInfo;
import com.kitty.game.rank.message.RespRankTopUser;
import com.kitty.game.rank.model.Range;
import com.kitty.game.rank.model.RankType;
import com.kitty.game.rank.model.pojo.DataUnit;
import com.kitty.game.rank.model.pojo.RankGroupListData;
import com.kitty.game.rank.model.record.RankRecord;
import com.kitty.game.rank.model.record.TowerRankRecord;
import lombok.extern.slf4j.Slf4j;
import org.nutz.dao.Dao;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import java.util.ArrayList;
import java.util.List;

/**通天塔挑战排行榜处理类*/
@Component
@Slf4j
public class TowerRankHandler extends RangeRankHandler {
    private List<Range<Short>> levelRanges = new ArrayList<>();

    /**初始化等级段*/
    @PostConstruct
    private void initRange() {
        levelRanges.add(new Range((short)50, (short)79));
        levelRanges.add(new Range((short) 80, (short) 89));
        levelRanges.add(new Range((short) 90, (short) 99));
        levelRanges.add(new Range((short) 100, (short) 109));
        levelRanges.add(new Range((short) 110, (short) 119));
        levelRanges.add(new Range((short) 120, (short) 129));
        levelRanges.add(new Range((short) 130, (short) 139));
        levelRanges.add(new Range((short) 140, (short) 149));
        levelRanges.add(new Range((short) 150, (short) 159));
        levelRanges.add(new Range((short) 160, (short) 169));
        levelRanges.add(new Range((short) 170, (short) 179));
    }

    /**从数据库加载排行榜数据*/
    @Override
    public void init() {
        Dao dao = SpringUtils.getBean(Dao.class);
        RankGroupListData<TowerRankRecord> rankGroupListData = dao.fetch(RankGroupListData.class, RankType.TOWER.name());
        if (rankGroupListData != null) {
            rankGroupListData.doAfterInit(TowerRankRecord.class);

            List<DataUnit> rankData = rankGroupListData.getRankData();
            for (DataUnit dataUnit : rankData) {
                String levelRange = dataUnit.getKey();
                for (RankRecord record : dataUnit.getRecords()) {
                    TowerRankRecord towerRankRecord = (TowerRankRecord) record;
                    update(levelRange, towerRankRecord.getGid(), record);
                }
            }
        }
    }

    public void save() {
        List<DataUnit> rankData = new ArrayList<>();
        for (Range<Short> range : levelRanges) {
            String levelRange = getLevelRange(range);
            List<RankRecord> records = getRecordsFrom(levelRange, 0, getRankSize());
            if (records == null || records.size() == 0) {continue ;}

            DataUnit dataUnit = new DataUnit(levelRange, records);
            rankData.add(dataUnit);
        }

        if (rankData.size() <= 0) {return ;}

        RankGroupListData<TowerRankRecord> rankGroupListData = new RankGroupListData<>(RankType.TOWER, rankData);
        rankGroupListData.doBeforeSave();
        Dao dao = SpringUtils.getBean(Dao.class);
        dao.insertOrUpdate(rankGroupListData);
    }

    @PreDestroy
    private void shutDown() {
        save();
        log.error("[{}]保存数据后关闭", this.getClass().getSimpleName());
    }

    private String getLevelRange(Range range) {
        return range.getMin() + "-" + range.getMax();
    }

    private Range getRange(short roleLevel) {
        for (Range<Short> range : levelRanges) {
            if (roleLevel >= range.getMin() && roleLevel <= range.getMax()) {
                return range;
            }
        }

        return null;
    }

    public RespRankTopUser getRankResponse(short type, String range) {
        RespRankTopUser respRankTopUser = new RespRankTopUser();
        respRankTopUser.setType(type);
        respRankTopUser.setCookie(new Long(System.currentTimeMillis() / 1000).intValue());
        respRankTopUser.setList(new ArrayList<>());
        List<PersonInfo> personInfoList = getPersonInfoList(getRecordsFrom(range, 0, getRankSize()));
        respRankTopUser.setList(personInfoList);
        respRankTopUser.setSize((short) respRankTopUser.getList().size());
        String[] levels = range.split("-");
        respRankTopUser.setMin(Short.parseShort(levels[0]));
        respRankTopUser.setMax(Short.parseShort(levels[1]));
        return respRankTopUser;
    }

    private List<PersonInfo> getPersonInfoList(List<RankRecord> records) {
        List<PersonInfo> list = new ArrayList<>(records.size());
        for (RankRecord rankRecord : records) {
            TowerRankRecord towerRankRecord = (TowerRankRecord)rankRecord;
            PersonInfo personInfo = new PersonInfo();
            personInfo.setList(new ArrayList<>());
            personInfo.getList().add(new FiedValue(305, towerRankRecord.getGid()));
            personInfo.getList().add(new FiedValue(1, towerRankRecord.getName()));
            personInfo.getList().add(new FiedValue(44, towerRankRecord.getPolar()));
            personInfo.getList().add(new FiedValue(864, towerRankRecord.getLayer()));
            personInfo.getList().add(new FiedValue(31, towerRankRecord.getLevel()));
            list.add(personInfo);
        }
        return list;
    }

    public void update(Role role, int layer) {
        Range range = getRange(role.getLevel());
        if (range == null) {return ;}

        String levelRange = getLevelRange(range);
        this.update(levelRange, role.getGid(), new TowerRankRecord(role.getGid(), layer, role.getName(), role.getLevel(), role.getPolar()));
    }

    /**角色升级跨等级段处理*/
    public void handleRoleUpgrade(Role role, short oldLevel, short newLevel) {
        /**判断角色是否跨等级段，是的话则从旧等级段排行榜删除，加入新等级段排行榜*/

        Range oldRange = getRange(oldLevel);
        Range newRange = getRange(newLevel);
        /**同一等级段时，返回*/
        if (oldRange != null && oldRange.equals(newRange)) {return ;}

        if (oldRange != null) {
            String oldLevelRange = getLevelRange(oldRange);

            TowerRankRecord rankRecord = (TowerRankRecord)remove(oldLevelRange, role.getGid());
            if (rankRecord != null) {
                String newLevelRange = getLevelRange(newRange);
                this.update(newLevelRange, role.getGid(), new TowerRankRecord(role.getGid(), rankRecord.getLayer(), role.getName(), role.getLevel(), role.getPolar()));
            }
        }
    }
}
